package trading_strategy.events;

import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;

/**
 * Created by IntelliJ IDEA.
 * User: gderoujoux
 * Date: 6 mai 2010
 * Time: 16:55:15
 * To change this template use File | Settings | File Templates.
 */
public class ListenerSpecificEventDispatcher implements EventListener {
    final LinkedList<AbstractMarketEvent> scheduledEvents = new LinkedList<AbstractMarketEvent>();
    EventListener listener;

    public ListenerSpecificEventDispatcher(EventListener listener) {
        this.listener = listener;
    }

    public void addScheduledEvent(AbstractMarketEvent event) {
        synchronized (scheduledEvents) {
            scheduledEvents.add(event);
            Collections.sort(scheduledEvents, new Comparator<AbstractMarketEvent>() {
                @Override
                public int compare(AbstractMarketEvent o1, AbstractMarketEvent o2) {
                    if (o1.getTs() > o2.getTs()) {
                        return 1;
                    } else if (o1.getTs() < o2.getTs()) {
                        return -1;
                    } else {
                        return 0;
                    }
                }
            });
        }
    }

    @Override
    public void onMarketEvent(AbstractMarketEvent event) {
        // Dispatch first the market event
        listener.onMarketEvent(event);

        // If needed, dispatch scheduled events
        if (!scheduledEvents.isEmpty()) {
            synchronized (scheduledEvents) {
                if (!scheduledEvents.isEmpty()) {
                    // Dispatch and remove all scheduled events that should happen before this event
                    AbstractMarketEvent addEvent = scheduledEvents.getFirst();
                    while (addEvent != null && event.getTs() >= addEvent.getTs()) {
                        listener.onMarketEvent(addEvent);
                        scheduledEvents.removeFirst();
                        addEvent = null;
                        if (!scheduledEvents.isEmpty()) {
                            addEvent = scheduledEvents.getFirst();
                        }
                    }
                }
            }
        }
    }
}
